#include <iostream>

#include <cstdlib>
#include <cmath>

#include "greedy.hh"

using namespace std;

/**
  * Cette fonction retourne de manière probabiliste une station en 
  * utilisant la méthode de la roulette.
  *
  * @param station Tableau des stations à considérer.
  * @param numberOfBTS Nombre de BTS total.
  *
  * @return Un pointeur vers la station séléctionnée.
  */
static BTS* fitnessProportionateSelector ( BTS* stations, uint numberOfBTS ) {
  double perCapitaSum = 0.0;
  for ( uint i = 0; i < numberOfBTS; ++i )
    perCapitaSum += (stations[i].known) ? 0.0 : 
      (double)stations[i].incomes / (double)stations[i].subscribers;

  if ( perCapitaSum == 0.0 ) {
    cerr << "No more stations..." << endl;
    return NULL;
  }

  double treshold = fmod ( rand(), perCapitaSum ) + 0;

  for ( uint i = 0; i < numberOfBTS; ++i ) {
    if ( !stations[i].known ) {
      treshold -= (double)stations[i].incomes / (double)stations[i].subscribers;

      if ( treshold <= 0 ) return &stations[i];
    }
  }

  cerr << "ERROR." << endl;
  return NULL;
}

vector < BTS* > greedy ( Dataset const& d ) {
  vector < BTS* > S;
  uint i = 0; uint subscribers = 0;

  for ( uint i = 0; i < d.numberOfBTS; ++i )
    d.stations[i].known = false;

  while ( i < d.numberOfBTS ) {
    checkTime();

    BTS* gChoice = fitnessProportionateSelector ( d.stations, d.numberOfBTS );
    i++;

    if ( gChoice != NULL && subscribers + gChoice->subscribers <= d.capacity ){ 
      S.push_back ( gChoice );
      subscribers += gChoice->subscribers;
      gChoice->known = true;
    }
  }

  for ( uint i = 0; i < d.numberOfBTS; ++i )
    d.stations[i].known = false;

  return S;
}
